package com.leyou.auth.service.impl;

import com.leyou.auth.constants.JwtConstants;
import com.leyou.auth.constants.RedisConstants;
import com.leyou.auth.dto.Payload;
import com.leyou.auth.dto.UserDetail;
import com.leyou.auth.service.UserAuthService;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.CookieUtils;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.UserDTO;
import feign.FeignException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class UserAuthServiceImpl implements UserAuthService {

    @Autowired
    private UserClient userClient;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void login(String username, String password, HttpServletResponse response) {

        try {
            // 1.根据页面传来的用户名和密码，到用户模块查询用户
            UserDTO user = this.userClient.queryUserNameAndPassword(username, password);

            // 2.判断查询结果 也就是校验数据
            // 校验用户信息 查不到用户信息 则抛出400的异常
            if (user == null) {

                throw new LyException(HttpStatus.BAD_REQUEST.value(),"用户名或密码错误！");

            }

            // 3.如果正确，生成Jwt凭证
            // 3.1准备信息
            UserDetail userDetail = UserDetail.of(user.getId(), user.getUsername());

            // 3.2 生成jwt
            String jwt = jwtUtils.createJwt(userDetail);

            // 4.把JWT写入用户cookie请求头中
            this.writeJwtInCookie(response,jwt);

        } catch (FeignException e) {

            // 把远程调用转换异常抛出
            throw new LyException(e.status(),e.contentUTF8());

        }


    }

    private void writeJwtInCookie(HttpServletResponse response, String jwt) {

        // 创建cookie对象 指定名称以及value值
        Cookie cookie = new Cookie(JwtConstants.COOKIE_NAME,jwt);

        // 指定cookie的作用域范围
        cookie.setDomain(JwtConstants.DOMAIN);

        // 禁止JS操作cookie
        cookie.setHttpOnly(true);

        // cookie有效期，-1就是跟随当前会话，浏览器关闭就消失
        cookie.setMaxAge(-1);

        // cookie作用的路径，/代表一切路径
        cookie.setPath("/");

        // 将cookie添加到响应头中返回给客户端
        response.addCookie(cookie);

    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response) {

        // 获取cookie信息然后从redis中删除

        try {
            // 1.获取用户cookie
            String token = CookieUtils.getCookieValue(request, JwtConstants.COOKIE_NAME);

            Payload payload = jwtUtils.parseJwt(token);

            Long id = payload.getUserDetail().getId();

            String key = RedisConstants.JTI_KEY_PREFIX + id;

            redisTemplate.delete(key);

        } catch (Exception e) {

            // 3.如果无效，什么都不做 此处相当于break，跳出当前try-catch
            return;

        }

        // 创建cookie对象 指定名称以及value值
        Cookie cookie = new Cookie(JwtConstants.COOKIE_NAME,"");

        // 指定cookie的作用域范围
        cookie.setDomain(JwtConstants.DOMAIN);

        // 禁止JS操作cookie
        cookie.setHttpOnly(true);

        // cookie有效期，-1就是跟随当前会话，浏览器关闭就消失
        cookie.setMaxAge(0);

        // cookie作用的路径，/代表一切路径
        cookie.setPath("/");

        // 将cookie添加到响应头中返回给客户端
        response.addCookie(cookie);

    }

}
